package sangpil.media
{
	import flash.display.Sprite;
	import flash.events.AsyncErrorEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.NetStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	
	import sangpil.events.MoviePlayerEvent;

	[Event(name="video_changing", type = "sangpil.events.MoviePlayerEvent")]
	[Event(name="video_changed", type = "sangpil.events.MoviePlayerEvent")]
	[Event(name="video_added", type = "sangpil.events.MoviePlayerEvent")]
	[Event(name="video_stoped", type = "sangpil.events.MoviePlayerEvent")]
	[Event(name="video_playing", type = "sangpil.events.MoviePlayerEvent")]
	public class MoviePlayer extends Sprite
	{
		public var video:Video;
		protected var videoURL:String;
		private var connection:NetConnection;
		public var stream:NetStream;
		private var client:Object;
		
		protected var metaData:Object;
		
		public function MoviePlayer(vURL:String = null)
		{
			super();
			this.videoURL = vURL;
			this.init();
		}
		
		private function init():void
		{
			this.client = new Object();
			this.client.onMetaData = nsMetaDataCallBack;
			this.connection = new NetConnection();
			this.connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			this.connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			this.connection.connect(null);
		}
		
		private function netStatusHandler(e:NetStatusEvent):void
		{
			switch(e.info.code)
			{
				case "NetConnection.Connect.Success":
					trace("video connect start");
                    connectStream();
                    break;
                case "NetStream.Play.StreamNotFound":
                    trace("Unable to locate video: " + videoURL);
                    break;
                case "NetStream.Play.Stop":
                	trace("stop");
                	this.removeEventListener(Event.ENTER_FRAME, throwCurrentTime);
                	this.dispatchEvent(new MoviePlayerEvent(metaData, MoviePlayerEvent.VIDEO_STOP));
                	break;
                case "NetStream.Seek.InvalidTime":
                	trace(e.info.code);
                	break;
                
			}
		}
		
		public function changeUrl(str:String):void
		{
			if(this.stream)
			{
				this.removeEventListener(Event.ENTER_FRAME, throwCurrentTime);
				
				stream.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
            	stream.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
				this.stream = null;
				stream = new NetStream(connection);
            	stream.client = client;
            	stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
            	stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
            	stream.play(str);
			}
		}
		
		public function pause():void
		{
			this.removeEventListener(Event.ENTER_FRAME, throwCurrentTime);
			this.stream.pause();
		}
		
		public function resume():void
		{
			this.stream.resume();
			this.addEventListener(Event.ENTER_FRAME, throwCurrentTime);
		}
		
        private function connectStream():void {
        	if(this.videoURL)
        	{
	            stream = new NetStream(connection);
	            stream.client = client;
	            stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
	            stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
	            stream.play(videoURL);
	        }else{
	        	trace("Movie Player : ready");
	        }
        }
		
        private function securityErrorHandler(e:SecurityErrorEvent):void {
            trace("securityErrorHandler: " + e);
        }
        
        private function asyncErrorHandler(e:AsyncErrorEvent):void {
            // ignore AsyncErrorEvent events.
        }
        
        protected function nsMetaDataCallBack(mdata:Object):void
        {
        	trace("MoviePlayer : Declare Video Instance");
        	this.metaData = mdata;
        	
        	if(this.video)
        	{
        		this.removeChild(this.video);
        		this.video = null;
        	}
        	this.video = new Video(mdata.width, mdata.height);
            video.attachNetStream(stream);
            this.addChildAt(video,0);
            this.stream.seek(0.01);
            /* for(var i:String in mdata)
            {
            	trace("n : "+i);
            } */
            this.addEventListener(Event.ENTER_FRAME, throwCurrentTime);
            this.dispatchEvent(new MoviePlayerEvent(this.metaData, MoviePlayerEvent.VIDEO_ADDED));
        }
		
		protected function throwCurrentTime(e:Event):void
		{
			var obj:Object = {current:this.stream.time, total:this.metaData.duration};
			this.dispatchEvent(new MoviePlayerEvent(obj, MoviePlayerEvent.VIDEO_PLAYING));
		}
	}
}